From 2c4cc07fe703e6383dca60ab115d808899e63136 Mon Sep 17 00:00:00 2001 From: "kaf24@firebug.cl.cam.ac.uk" Date: Wed, 8 Jun 2005 14:05:21 +0000 Subject: [PATCH] bitkeeper revision 1.1691.1.8 (42a6fb21d3oJwpLmOxa2jKHRJ-8fJg) First phase of removing IRQ numbers from Xen (transitioning to IRQ addressing by 'legacy ISA IRQ', 'interrupt vector', and 'I/O APIC address + pin' as appropriate). Overall plan is to move I/O APIC parsing and setup out of Xen (so we start DOM0 in virtual wire mode). Signed-off-by: Keir Fraser --- xen/arch/ia64/irq.c | 22 ---------- xen/arch/x86/i8259.c | 47 +++++++-------------- xen/arch/x86/io_apic.c | 40 ++++++++---------- xen/arch/x86/irq.c | 79 +++++++++++++---------------------- xen/arch/x86/physdev.c | 3 +- xen/arch/x86/smpboot.c | 6 --- xen/include/asm-x86/hardirq.h | 4 +- xen/include/asm-x86/irq.h | 19 ++++----- xen/include/xen/irq.h | 1 - 9 files changed, 72 insertions(+), 149 deletions(-) diff --git a/xen/arch/ia64/irq.c b/xen/arch/ia64/irq.c index 5d4fda28a4..473e0afdae 100644 --- a/xen/arch/ia64/irq.c +++ b/xen/arch/ia64/irq.c @@ -1471,28 +1471,6 @@ int pirq_guest_unbind(struct domain *d, int irq) return 0; } -int pirq_guest_bindable(int irq, int will_share) -{ - irq_desc_t *desc = &irq_desc[irq]; - irq_guest_action_t *action; - unsigned long flags; - int okay; - - spin_lock_irqsave(&desc->lock, flags); - - action = (irq_guest_action_t *)desc->action; - - /* - * To be bindable the IRQ must either be not currently bound (1), or - * it must be shareable (2) and not at its share limit (3). - */ - okay = ((!(desc->status & IRQ_GUEST) && (action == NULL)) || /* 1 */ - (action->shareable && will_share && /* 2 */ - (action->nr_guests != IRQ_MAX_GUESTS))); /* 3 */ - - spin_unlock_irqrestore(&desc->lock, flags); - return okay; -} #endif #ifdef XEN diff --git a/xen/arch/x86/i8259.c b/xen/arch/x86/i8259.c index 91bc24f5d9..7e7571fd38 100644 --- a/xen/arch/x86/i8259.c +++ b/xen/arch/x86/i8259.c @@ -43,28 +43,10 @@ BUILD_COMMON_IRQ() BI(x,8) BI(x,9) BI(x,a) BI(x,b) \ BI(x,c) BI(x,d) BI(x,e) BI(x,f) -/* - * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: - * (these are usually mapped to vectors 0x20-0x2f) - */ -BUILD_16_IRQS(0x0) - -#ifdef CONFIG_X86_IO_APIC -/* - * The IO-APIC gives us many more interrupt sources. Most of these - * are unused but an SMP system is supposed to have enough memory ... - * sometimes (mostly wrt. hw bugs) we get corrupted vectors all - * across the spectrum, so we really want to be prepared to get all - * of these. Plus, more powerful systems might have more than 64 - * IO-APIC registers. - * - * (these are usually mapped into the 0x20-0xff vector range) - */ -BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) +BUILD_16_IRQS(0x0) BUILD_16_IRQS(0x1) BUILD_16_IRQS(0x2) BUILD_16_IRQS(0x3) BUILD_16_IRQS(0x4) BUILD_16_IRQS(0x5) BUILD_16_IRQS(0x6) BUILD_16_IRQS(0x7) BUILD_16_IRQS(0x8) BUILD_16_IRQS(0x9) BUILD_16_IRQS(0xa) BUILD_16_IRQS(0xb) -BUILD_16_IRQS(0xc) -#endif +BUILD_16_IRQS(0xc) BUILD_16_IRQS(0xd) BUILD_16_IRQS(0xe) BUILD_16_IRQS(0xf) #undef BUILD_16_IRQS #undef BI @@ -101,15 +83,11 @@ BUILD_SMP_INTERRUPT(spurious_interrupt,SPURIOUS_APIC_VECTOR) IRQ(x,8), IRQ(x,9), IRQ(x,a), IRQ(x,b), \ IRQ(x,c), IRQ(x,d), IRQ(x,e), IRQ(x,f) - void (*interrupt[NR_IRQS])(void) = { - IRQLIST_16(0x0), - -#ifdef CONFIG_X86_IO_APIC - IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), + static void (*interrupt[])(void) = { + IRQLIST_16(0x0), IRQLIST_16(0x1), IRQLIST_16(0x2), IRQLIST_16(0x3), IRQLIST_16(0x4), IRQLIST_16(0x5), IRQLIST_16(0x6), IRQLIST_16(0x7), IRQLIST_16(0x8), IRQLIST_16(0x9), IRQLIST_16(0xa), IRQLIST_16(0xb), - IRQLIST_16(0xc) -#endif + IRQLIST_16(0xc), IRQLIST_16(0xd), IRQLIST_16(0xe), IRQLIST_16(0xf) }; #undef IRQ @@ -128,7 +106,7 @@ spinlock_t i8259A_lock = SPIN_LOCK_UNLOCKED; static void end_8259A_irq (unsigned int irq) { - if (!(irq_desc[irq].status & (IRQ_DISABLED|IRQ_INPROGRESS))) + if (!(irq_desc[irq_to_vector(irq)].status & (IRQ_DISABLED|IRQ_INPROGRESS))) enable_8259A_irq(irq); } @@ -225,7 +203,7 @@ void make_8259A_irq(unsigned int irq) { disable_irq_nosync(irq); io_apic_irqs &= ~(1<pin mappings. Sometimes there are @@ -657,21 +659,11 @@ static struct hw_interrupt_type ioapic_edge_type; static inline void ioapic_register_intr(int irq, int vector, unsigned long trigger) { - if (use_pci_vector() && !platform_legacy_irq(irq)) { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[vector].handler = &ioapic_level_type; - else - irq_desc[vector].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[vector]); - } else { - if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || - trigger == IOAPIC_LEVEL) - irq_desc[irq].handler = &ioapic_level_type; - else - irq_desc[irq].handler = &ioapic_edge_type; - set_intr_gate(vector, interrupt[irq]); - } + if ((trigger == IOAPIC_AUTO && IO_APIC_irq_trigger(irq)) || + trigger == IOAPIC_LEVEL) + irq_desc[vector].handler = &ioapic_level_type; + else + irq_desc[vector].handler = &ioapic_edge_type; } void __init setup_IO_APIC_irqs(void) @@ -781,7 +773,7 @@ void __init setup_ExtINT_IRQ0_pin(unsigned int pin, int vector) * The timer IRQ doesn't have to know that behind the * scene we have a 8259A-master in AEOI mode ... */ - irq_desc[0].handler = &ioapic_edge_type; + irq_desc[IO_APIC_VECTOR(0)].handler = &ioapic_edge_type; /* * Add it to the IO-APIC irq-routing table: @@ -1176,7 +1168,7 @@ static unsigned int startup_edge_ioapic_irq(unsigned int irq) */ static void ack_edge_ioapic_irq(unsigned int irq) { - if ((irq_desc[irq].status & (IRQ_PENDING | IRQ_DISABLED)) + if ((irq_desc[IO_APIC_VECTOR(irq)].status & (IRQ_PENDING | IRQ_DISABLED)) == (IRQ_PENDING | IRQ_DISABLED)) mask_IO_APIC_irq(irq); ack_APIC_irq(); @@ -1354,11 +1346,13 @@ static inline void init_IO_APIC_traps(void) */ for (irq = 0; irq < NR_IRQS ; irq++) { int tmp = irq; +#if 0 if (use_pci_vector()) { if (!platform_legacy_irq(tmp)) if ((tmp = vector_to_irq(tmp)) == -1) continue; } +#endif if (IO_APIC_IRQ(tmp) && !IO_APIC_VECTOR(tmp)) { /* * Hmm.. We don't have an entry for this, @@ -1367,9 +1361,6 @@ static inline void init_IO_APIC_traps(void) */ if (irq < 16) make_8259A_irq(irq); - else - /* Strange. Oh, well.. */ - irq_desc[irq].handler = &no_irq_type; } } } @@ -1485,7 +1476,10 @@ static inline void check_timer(void) */ disable_8259A_irq(0); vector = assign_irq_vector(0); - set_intr_gate(vector, interrupt[0]); + + irq_desc[IO_APIC_VECTOR(0)].action = irq_desc[LEGACY_VECTOR(0)].action; + irq_desc[IO_APIC_VECTOR(0)].depth = 0; + irq_desc[IO_APIC_VECTOR(0)].status &= ~IRQ_DISABLED; /* * Subtle, code in do_timer_interrupt() expects an AEOI @@ -1546,7 +1540,7 @@ static inline void check_timer(void) printk(KERN_INFO "...trying to set up timer as Virtual Wire IRQ..."); disable_8259A_irq(0); - irq_desc[0].handler = &lapic_irq_type; + irq_desc[vector].handler = &lapic_irq_type; apic_write_around(APIC_LVT0, APIC_DM_FIXED | vector); /* Fixed mode */ enable_8259A_irq(0); @@ -1834,7 +1828,7 @@ int ioapic_guest_write(int apicid, int address, u32 val) return 0; /* Set the correct irq-handling type. */ - irq_desc[irq].handler = rte.trigger ? + irq_desc[IO_APIC_VECTOR(irq)].handler = rte.trigger ? &ioapic_level_type: &ioapic_edge_type; /* Record the pin<->irq mapping. */ diff --git a/xen/arch/x86/irq.c b/xen/arch/x86/irq.c index fe9633972c..2d5335af28 100644 --- a/xen/arch/x86/irq.c +++ b/xen/arch/x86/irq.c @@ -16,7 +16,7 @@ irq_desc_t irq_desc[NR_IRQS]; -static void __do_IRQ_guest(int irq); +static void __do_IRQ_guest(int vector); void no_action(int cpl, void *dev_id, struct cpu_user_regs *regs) { } @@ -46,7 +46,8 @@ atomic_t irq_err_count; inline void disable_irq_nosync(unsigned int irq) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int vector = irq_to_vector(irq); + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -60,15 +61,10 @@ inline void disable_irq_nosync(unsigned int irq) spin_unlock_irqrestore(&desc->lock, flags); } -void disable_irq(unsigned int irq) -{ - disable_irq_nosync(irq); - do { smp_mb(); } while ( irq_desc[irq].status & IRQ_INPROGRESS ); -} - void enable_irq(unsigned int irq) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int vector = irq_to_vector(irq); + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock, flags); @@ -77,10 +73,7 @@ void enable_irq(unsigned int irq) { desc->status &= ~IRQ_DISABLED; if ( (desc->status & (IRQ_PENDING | IRQ_REPLAY)) == IRQ_PENDING ) - { desc->status |= IRQ_REPLAY; - hw_resend_irq(desc->handler,irq); - } desc->handler->enable(irq); } @@ -88,9 +81,10 @@ void enable_irq(unsigned int irq) } asmlinkage void do_IRQ(struct cpu_user_regs *regs) -{ - unsigned int irq = regs->entry_vector; - irq_desc_t *desc = &irq_desc[irq]; +{ + unsigned int vector = regs->entry_vector; + unsigned int irq = vector_to_irq(vector); + irq_desc_t *desc = &irq_desc[vector]; struct irqaction *action; perfc_incrc(irqs); @@ -100,7 +94,7 @@ asmlinkage void do_IRQ(struct cpu_user_regs *regs) if ( likely(desc->status & IRQ_GUEST) ) { - __do_IRQ_guest(irq); + __do_IRQ_guest(vector); spin_unlock(&desc->lock); return; } @@ -121,11 +115,11 @@ asmlinkage void do_IRQ(struct cpu_user_regs *regs) while ( desc->status & IRQ_PENDING ) { desc->status &= ~IRQ_PENDING; - irq_enter(smp_processor_id(), irq); + irq_enter(smp_processor_id()); spin_unlock_irq(&desc->lock); action->handler(irq, action->dev_id, regs); spin_lock_irq(&desc->lock); - irq_exit(smp_processor_id(), irq); + irq_exit(smp_processor_id()); } desc->status &= ~IRQ_INPROGRESS; @@ -137,7 +131,8 @@ asmlinkage void do_IRQ(struct cpu_user_regs *regs) void free_irq(unsigned int irq) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int vector = irq_to_vector(irq); + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); @@ -148,12 +143,13 @@ void free_irq(unsigned int irq) spin_unlock_irqrestore(&desc->lock,flags); /* Wait to make sure it's not being used on another CPU */ - do { smp_mb(); } while ( irq_desc[irq].status & IRQ_INPROGRESS ); + do { smp_mb(); } while ( desc->status & IRQ_INPROGRESS ); } int setup_irq(unsigned int irq, struct irqaction *new) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int vector = irq_to_vector(irq); + irq_desc_t *desc = &irq_desc[vector]; unsigned long flags; spin_lock_irqsave(&desc->lock,flags); @@ -187,9 +183,10 @@ typedef struct { struct domain *guest[IRQ_MAX_GUESTS]; } irq_guest_action_t; -static void __do_IRQ_guest(int irq) +static void __do_IRQ_guest(int vector) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int irq = vector_to_irq(vector); + irq_desc_t *desc = &irq_desc[vector]; irq_guest_action_t *action = (irq_guest_action_t *)desc->action; struct domain *d; int i; @@ -218,7 +215,7 @@ int pirq_guest_unmask(struct domain *d) j = find_first_set_bit(m); m &= ~(1 << j); pirq = (i << 5) + j; - desc = &irq_desc[pirq]; + desc = &irq_desc[irq_to_vector(pirq)]; spin_lock_irq(&desc->lock); if ( !test_bit(d->pirq_to_evtchn[pirq], &s->evtchn_mask[0]) && test_and_clear_bit(pirq, &d->pirq_mask) && @@ -233,8 +230,9 @@ int pirq_guest_unmask(struct domain *d) int pirq_guest_bind(struct vcpu *v, int irq, int will_share) { + unsigned int vector = irq_to_vector(irq); struct domain *d = v->domain; - irq_desc_t *desc = &irq_desc[irq]; + irq_desc_t *desc = &irq_desc[vector]; irq_guest_action_t *action; unsigned long flags; int rc = 0; @@ -243,6 +241,9 @@ int pirq_guest_bind(struct vcpu *v, int irq, int will_share) if ( !IS_CAPABLE_PHYSDEV(d) ) return -EPERM; + if ( vector == 0 ) + return -EBUSY; + spin_lock_irqsave(&desc->lock, flags); action = (irq_guest_action_t *)desc->action; @@ -303,11 +304,14 @@ int pirq_guest_bind(struct vcpu *v, int irq, int will_share) int pirq_guest_unbind(struct domain *d, int irq) { - irq_desc_t *desc = &irq_desc[irq]; + unsigned int vector = irq_to_vector(irq); + irq_desc_t *desc = &irq_desc[vector]; irq_guest_action_t *action; unsigned long flags; int i; + BUG_ON(vector == 0); + spin_lock_irqsave(&desc->lock, flags); action = (irq_guest_action_t *)desc->action; @@ -337,26 +341,3 @@ int pirq_guest_unbind(struct domain *d, int irq) spin_unlock_irqrestore(&desc->lock, flags); return 0; } - -int pirq_guest_bindable(int irq, int will_share) -{ - irq_desc_t *desc = &irq_desc[irq]; - irq_guest_action_t *action; - unsigned long flags; - int okay; - - spin_lock_irqsave(&desc->lock, flags); - - action = (irq_guest_action_t *)desc->action; - - /* - * To be bindable the IRQ must either be not currently bound (1), or - * it must be shareable (2) and not at its share limit (3). - */ - okay = ((!(desc->status & IRQ_GUEST) && (action == NULL)) || /* 1 */ - (action->shareable && will_share && /* 2 */ - (action->nr_guests != IRQ_MAX_GUESTS))); /* 3 */ - - spin_unlock_irqrestore(&desc->lock, flags); - return okay; -} diff --git a/xen/arch/x86/physdev.c b/xen/arch/x86/physdev.c index 6eba1bfb22..1cbed74240 100644 --- a/xen/arch/x86/physdev.c +++ b/xen/arch/x86/physdev.c @@ -60,7 +60,7 @@ long do_physdev_op(physdev_op_t *uop) break; op.u.irq_status_query.flags = 0; /* Edge-triggered interrupts don't need an explicit unmask downcall. */ - if ( strstr(irq_desc[irq].handler->typename, "edge") == NULL ) + if ( strstr(irq_desc[irq_to_vector(irq)].handler->typename, "edge") == NULL ) op.u.irq_status_query.flags |= PHYSDEVOP_IRQ_NEEDS_UNMASK_NOTIFY; ret = 0; break; @@ -89,7 +89,6 @@ long do_physdev_op(physdev_op_t *uop) return -EINVAL; op.u.irq_op.vector = assign_irq_vector(irq); - set_intr_gate(op.u.irq_op.vector, interrupt[irq]); ret = 0; break; diff --git a/xen/arch/x86/smpboot.c b/xen/arch/x86/smpboot.c index 382fee8d15..f276e9632e 100644 --- a/xen/arch/x86/smpboot.c +++ b/xen/arch/x86/smpboot.c @@ -1177,12 +1177,6 @@ void __init smp_cpus_done(unsigned int max_cpus) #if 0 void __init smp_intr_init(void) { - /* - * IRQ0 must be given a fixed assignment and initialized, - * because it's used before the IO-APIC is set up. - */ - set_intr_gate(FIRST_DEVICE_VECTOR, interrupt[0]); - /* * The reschedule interrupt is a CPU-to-CPU reschedule-helper * IPI, driven by wakeup. diff --git a/xen/include/asm-x86/hardirq.h b/xen/include/asm-x86/hardirq.h index 576efd3c7c..04fa38b4be 100644 --- a/xen/include/asm-x86/hardirq.h +++ b/xen/include/asm-x86/hardirq.h @@ -15,7 +15,7 @@ typedef struct { #define in_irq() (local_irq_count(smp_processor_id()) != 0) -#define irq_enter(cpu, irq) (local_irq_count(cpu)++) -#define irq_exit(cpu, irq) (local_irq_count(cpu)--) +#define irq_enter(cpu) (local_irq_count(cpu)++) +#define irq_exit(cpu) (local_irq_count(cpu)--) #endif /* __ASM_HARDIRQ_H */ diff --git a/xen/include/asm-x86/irq.h b/xen/include/asm-x86/irq.h index 97f143ad44..5238b03ae1 100644 --- a/xen/include/asm-x86/irq.h +++ b/xen/include/asm-x86/irq.h @@ -8,17 +8,20 @@ #include #include -extern void disable_irq(unsigned int); +#define IO_APIC_IRQ(irq) (((irq) >= 16) || ((1<<(irq)) & io_apic_irqs)) +#define IO_APIC_VECTOR(irq) (irq_vector[irq]) +#define LEGACY_VECTOR(irq) ((irq) + FIRST_EXTERNAL_VECTOR) +#define irq_to_vector(irq) \ + (IO_APIC_IRQ(irq) ? IO_APIC_VECTOR(irq) : LEGACY_VECTOR(irq)) +#define vector_to_irq(vec) (vector_irq[vec]) + extern void disable_irq_nosync(unsigned int); extern void enable_irq(unsigned int); extern int vector_irq[NR_VECTORS]; extern u8 irq_vector[NR_IRQ_VECTORS]; -#define IO_APIC_VECTOR(irq) irq_vector[irq] #define AUTO_ASSIGN -1 -extern void (*interrupt[NR_IRQS])(void); - #define platform_legacy_irq(irq) ((irq) < 16) void disable_8259A_irq(unsigned int irq); @@ -40,12 +43,4 @@ extern unsigned long io_apic_irqs; extern atomic_t irq_err_count; extern atomic_t irq_mis_count; -#define IO_APIC_IRQ(x) (((x) >= 16) || ((1<<(x)) & io_apic_irqs)) - -static inline void hw_resend_irq(struct hw_interrupt_type *h, unsigned int i) -{ - if (IO_APIC_IRQ(i)) - send_IPI_self(IO_APIC_VECTOR(i)); -} - #endif /* _ASM_HW_IRQ_H */ diff --git a/xen/include/xen/irq.h b/xen/include/xen/irq.h index 0bc8558ae0..7b1f826198 100644 --- a/xen/include/xen/irq.h +++ b/xen/include/xen/irq.h @@ -71,6 +71,5 @@ struct vcpu; extern int pirq_guest_unmask(struct domain *p); extern int pirq_guest_bind(struct vcpu *p, int irq, int will_share); extern int pirq_guest_unbind(struct domain *p, int irq); -extern int pirq_guest_bindable(int irq, int will_share); #endif /* __XEN_IRQ_H__ */ -- 2.30.2